import { computed, defineComponent, onMounted, reactive, ref, Teleport } from "vue";
import styles from "./Table.module.less";
import OperationBtns from "./OperationBtns/OperationBtns";
import SearchForm from "./SearchForm/SearchForm";
import { analysisRolesAndOr, analysisPermissionsAndOr } from "@/common/auth/auth";
import Toolbar from "./Toolbar/Toolbar";
import _ from "lodash";
import to from "await-to-js";
import { message } from "ant-design-vue";
export default defineComponent({
  props: {
    tableConfig: {
      type: Object,
      required: true,
    }
  },
  setup(props, { expose }) {
    const state = reactive({
      dataSource: [],
      loading: false,
      pagination: props.tableConfig.pagination ? {
        total: 0,
        current: 1,
        pageSize: 10,
        showTotal: (total) => `总数：${total}`
      } : null,
    })

    const searchFormShow = ref(false);

    // 表格筛选条件
    const searchForm = ref({});

    const searchConfirm = (e: any) => {
      searchForm.value = e;
      init();
      getList();
    }

    // 初始化
    const init = async () => {
      state.dataSource = [];
      if (props.tableConfig.pagination && state.pagination) {
        state.pagination.total = 0;
        state.pagination.current = 1;
        state.pagination.pageSize = 10;
      }
    }

    // 表格状态变更
    const tableChangeHandler = (pag: { pageSize: number; current: number }) => {
      if (state.pagination) {
        state.pagination.current = pag.current;
        state.pagination.pageSize = pag.pageSize;
        getList();
      }
    };

    // 刷新
    const refresh = async () => {
      init();
      getList();
    }

    // 主动刷新
    const refreshHandler = _.debounce(async () => {
      await refresh();
      props.tableConfig.toolbar?.refresh?.handler?.();
    }, 300, { leading: true, trailing: false })

    const tableSourceFormat = {
      data: props.tableConfig?.tableSourceFormat?.data ? props.tableConfig.tableSourceFormat.data : 'data',
      pageSize: props.tableConfig?.tableSourceFormat?.pageSize ? props.tableConfig.tableSourceFormat.pageSize : 'pageSize',
      current: props.tableConfig?.tableSourceFormat?.current ? props.tableConfig.tableSourceFormat.current : 'pageNum',
      total: props.tableConfig?.tableSourceFormat?.total ? props.tableConfig.tableSourceFormat.total : 'total'
    }

    // 获取列表
    const getList = async () => {
      state.loading = true;
      try {
        const query = props.tableConfig.query || {};
        let pageParams: any = {};
        if (props.tableConfig.pagination && state.pagination) {
          pageParams[tableSourceFormat.pageSize] = state.pagination?.pageSize || 10;
          pageParams[tableSourceFormat.current] = state.pagination?.current || 1;
        }
        const [err, res]: any = await to(props.tableConfig.service.getTable({ ...query, ...pageParams, ...searchForm.value }));
        if (!err) {
          state.dataSource = res?.data?.[tableSourceFormat?.data] || [];
          (props.tableConfig.pagination && state.pagination) && (state.pagination.total = res?.data?.[tableSourceFormat.total] || 0);
        }
      } finally {
        state.loading = false;
      }
    }
    // 操作栏宽度
    const operationWidth = computed(() => {
      return props.tableConfig.operationWidth;
    })
    // 列
    const columns = ref([]);
    let columnsClone = _.cloneDeep(props.tableConfig.columns);
    if (props.tableConfig.operation) {
      let operationCol: any = {
        fixed: "right",
        title: "操作",
        dataIndex: "operation",
        align: "center",
      };
      operationWidth.value && (operationCol.width = operationWidth.value);
      columnsClone.push(operationCol);
    }
    columns.value = columnsClone;
    onMounted(() => {
      getList();
    })
    // 删除单行
    const deleteRow = async (record) => {
      let [err, res]: any = [true, null];
      // 有单独删除接口使用单独删除接口,没有则使用批量删除单元素数组传参方式
      if (props?.tableConfig?.service?.delete) {
        [err, res] = await to(props.tableConfig.service.delete(record[props.tableConfig.rowKey]));
      } else {
        [err, res] = await to(props.tableConfig.service.deleteMultiple([record[props.tableConfig.rowKey]]));
      }
      if (!err) {
        message.success("删除成功!");
        props.tableConfig?.toolbar?.delete?.handler?.();
        getList();
      }
      return [err, res];
    }
    const popupsRef = ref([] as any[]);
    props.tableConfig.popups.forEach(item => {
      popupsRef.value.push(ref(null));
    })
    const getPopup = (key) => {
      const idx = props.tableConfig.popups.findIndex(x => x.ref === key);
      for (let i = 0; i <= popupsRef.value.length; i++) {
        if (idx === i) {
          return popupsRef.value[i];
        }
      }
    }
    // 重载
    const reload = ({ reloadPagination } = { reloadPagination: false }) => {
      if (reloadPagination) {
        init();
      }
      getList();
    }
    expose({
      getPopup,
      reload,
    })
    return () => (
      <div class={styles['table-container']}>
        {Object.keys(props?.tableConfig?.searchForm || {}).length > 0 && <SearchForm fields={props.tableConfig.searchForm} v-show={searchFormShow.value} onConfirm={(e: any) => { searchConfirm(e) }} />}
        <Toolbar config={props.tableConfig.toolbar} v-model:columns={columns.value} onRefreshHandler={() => { refreshHandler() }} onSearch={() => { searchFormShow.value = !searchFormShow.value }} />
        <a-table
          bordered={true}
          scroll={{ x: "max-content" }}
          dataSource={state.dataSource}
          columns={columns.value}
          loading={state.loading}
          rowKey={props.tableConfig.rowKey}
          pagination={props.tableConfig.pagination ? state.pagination : false}
          onChange={tableChangeHandler}
          v-slots={{
            bodyCell: ({ text, record, index, column }) => {
              if (column.dataIndex === 'operation') {
                let arr: any[] = [];
                props.tableConfig.operation({ text, record, index, column }).forEach(x => {
                  if ((!x.permissions || analysisPermissionsAndOr(x.permissions)) && (!x.roles || analysisRolesAndOr(x.roles))) {
                    arr.push(x);
                  }
                })
                return <OperationBtns btns={arr} origin={{ text, record, index, column }} onDeleteRow={() => { deleteRow(record) }} />;
              }
              if (props.tableConfig?.bodyCell) {
                return props.tableConfig.bodyCell({ text, record, index, column });
              }
            }
          }}
          {...props.tableConfig.otherAttrs}
        />
        <Teleport to="body">
          {
            props.tableConfig.popups.map((item: any, index: number) => {
              const el: any = item.dom();
              return <el ref={popupsRef.value[index]} service={props.tableConfig.service} />;
            })
          }
        </Teleport>
      </div>
    )
  }
})